package com.nikolaj.kuzan.utils;

import net.coobird.thumbnailator.Thumbnails;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.io.IOException;

public class DataTransformer {

    int outputImageSize;

    public Double[] imgToInputVector(BufferedImage image, boolean croppImage, int imageSize) throws IOException {

        outputImageSize = imageSize;



        byte[] pixelsRGB = ((DataBufferByte) image.getRaster().getDataBuffer())
                .getData();
        byte[] pixels = new byte[pixelsRGB.length / 3]; // 3 - count of colors
        // (RGB)

        for (int i = 0; i < pixelsRGB.length; i++) {
            if (pixelsRGB[i] < 0) {
                pixelsRGB[i] = 0;
            } else {
                pixelsRGB[i] = 1;
            }
        }


        for (int i = 0, j = 0; i < pixelsRGB.length; i = i + 3) {
            pixels[j] = (byte) (pixelsRGB[i] + pixelsRGB[i + 1] + pixelsRGB[i + 2]);
            j++;
        }

        for (int i = 0; i < pixels.length; i++) {
            if (pixels[i] != 0) {
                pixels[i] = 1;
            }
        }


        byte[][] pixelMatrix = new byte[(int) Math.sqrt(pixels.length)][(int) Math
                .sqrt(pixels.length)];

        for (int i = 0; i < pixelMatrix.length; i++) {
            for (int j = 0; j < pixelMatrix[i].length; j++) {
                pixelMatrix[i][j] = pixels[i * (pixelMatrix.length) + j];
            }
        }


        int[][] croppedImage;

        if (croppImage) {
            croppedImage = croppPixelMatrix(pixelMatrix);
        } else {
            croppedImage = new int[pixelMatrix.length][pixelMatrix[0].length];
            for (int i = 0; i < pixelMatrix.length; i++) {
                for (int j = 0; j < pixelMatrix.length; j++) {
                    croppedImage[i][j] = pixelMatrix[i][j];
                }
            }
        }

        /*

        int[][] croppedImageRGB = new int[croppedImage.length][croppedImage[0].length * 3];

        for (int i = 0; i < croppedImage.length; i++) {
            for (int j = 0, k = 0; j < croppedImage[i].length; j++) {
                croppedImageRGB[i][k] = croppedImage[i][j];
                k++;
                croppedImageRGB[i][k] = croppedImage[i][j];
                k++;
                croppedImageRGB[i][k] = croppedImage[i][j];
                k++;
            }
        }


        for (int i = 0; i < croppedImageRGB.length; i++) {
            for (int j = 0; j < croppedImageRGB[i].length; j++) {
                if (croppedImageRGB[i][j] == 0) {
                    croppedImageRGB[i][j] = 255;
                }
            }
        }*/


        for (int i = 0; i < croppedImage.length; i++) {
            for (int j = 0; j < croppedImage[i].length; j++) {
                System.out.print(croppedImage[i][j]);
            }
            System.out.println();
        }





        BufferedImage image2 = ImageExport.convertRGBImage(croppedImage);/**/

        image2 = Thumbnails.of(image2).forceSize(outputImageSize, outputImageSize).asBufferedImage();



        int[] inputVectorInt = ((DataBufferInt) image2.getRaster().getDataBuffer()).getData();

        System.out.println("------------------++++++++++++++------------"+ inputVectorInt.length+"--------+++++++++----");

        double[] inputVector = new double[inputVectorInt.length];
        for (int i = 0; i < inputVector.length; i++) {
            inputVector[i] = inputVectorInt[i];
        }


/*
        for (int i = 0; i < inputVector.length; i++) {
            if (inputVector[i] == 255) {
                inputVector[i] = 0;
            } else {
                inputVector[i] = 1;
            }
        }
*/
        System.out.print("------------------INPUT VECTOR-----------------------");
        Printer.printImg(DoubleConverter.doubleArrToObjectDoubleArr(inputVector), outputImageSize);
        System.out.println("-*-*-*-*-*-*-*-INPUT VECTOR-*-*-*-*-*-*-*-*-*-*-*-*");

        //convert double[] to Double[]
        return DoubleConverter.doubleArrToObjectDoubleArr(inputVector);
    }

    private int[][] croppPixelMatrix(byte[][] pixelMatrix) {
        int summ = 0, firstLine = 0, lastLine = 0, firstColumn = 0, lastColumn = 0;

        boolean flag = false;

        for (int i = 0; i < pixelMatrix.length; i++) {
            for (int j = 0; j < pixelMatrix[i].length; j++) {
                summ = summ + pixelMatrix[i][j];
            }
            if (summ != 0) {
                flag = true;
            } else if (summ == 0 && flag == false) {
                firstLine++;
            } else if (summ == 0 && flag == true) {
                lastLine = i - 1;
                break;
            }
            summ = 0;
        }

        // ????? ??????? ??????? ? ????????????
        flag = false;
        int minFirstColumn = pixelMatrix.length;

        for (int i = 0; i < pixelMatrix.length; i++) {
            for (int j = 0; j < pixelMatrix[i].length; j++) {
                summ = summ + pixelMatrix[i][j];
                if (summ != 0) {
                    flag = true;
                } else if (summ == 0 && flag == false) {
                    firstColumn++;
                }
            }
            if (firstColumn < minFirstColumn) {
                minFirstColumn = firstColumn;
            }

            firstColumn = summ = 0;
            flag = false;
        }

        int maxLastColumn = 0;

        for (int i = 0; i < pixelMatrix.length; i++) {
            for (int j = pixelMatrix[i].length - 1; j >= 0; j--) {
                summ = summ + pixelMatrix[i][j];
                if (summ != 0) {
                    flag = true;
                } else if (summ == 0 && flag == false) {
                    lastColumn++;
                }
            }

            if ((pixelMatrix.length - lastColumn) > maxLastColumn) {
                maxLastColumn = pixelMatrix.length - lastColumn;
            }

            lastColumn = summ = 0;
            flag = false;
        }


        int newWidth = maxLastColumn - minFirstColumn;
        int newHeight = lastLine - firstLine + 1;

        int[][] croppedPixelMatrix = new int[newHeight][newWidth];
        for (int i = 0; i < croppedPixelMatrix.length; i++) {
            for (int j = 0; j < croppedPixelMatrix[i].length; j++) {
                croppedPixelMatrix[i][j] = pixelMatrix[firstLine + i][minFirstColumn + j];
            }
        }

        return croppedPixelMatrix;
    }

    public BufferedImage imgVectorToImg(Double[] imgVector, int imgSize){

        int [][] rgbValue = new int[imgSize][imgSize];
        for(int i = 0; i < imgSize; i++){
            for (int j = 0; j < imgSize; j++){
                rgbValue[i][j] = imgVector[i*imgSize + j].intValue();
            }
        }

        int height = rgbValue.length;
        int width = rgbValue[0].length;

        Color myWhite = new Color(255, 255, 255); // Color white
        int rgbWhite = myWhite.getRGB();
        Color myBlack = new Color(0, 0, 0); // Color black
        int rgbBlack = myBlack.getRGB();


        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //we either have to loop through all values, or convert to 1-d array
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if(rgbValue[y][x] == 0){
                    bufferedImage.setRGB(x, y, rgbWhite);
                } else {
                    bufferedImage.setRGB(x, y, rgbBlack);
                }
            }
        }

        try {
            ImageExport.exportImageToFile("E:/i.jpg", bufferedImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bufferedImage;
    }
}
